#ifndef __TINY_TEST__

#include "vbb_STORAGE.h"
#include <string.h>
#include <stdio.h>
#include "vbb_flashmem.h"
#include <stdlib.h>
#include "vbb_Header.h"
#include "vbb_FirmwareUtils.h"

#define STORAGE_ADDR_CONFIG     16711680
#define STORAGE_MAX_CONFIG      256
#define STORAGE_PAGE_SIZE       256

extern VBB_FlashMem flashMem;
VBB_Storage storage;

void STORAGE_DefaultConfig(VBB_Config * Config)
{
    strcpy(Config->OwnerId, "SOMECORP");
    strcpy(Config->VehicleId, "VEHICLE0");
    strcpy(Config->PlateNumber, "29A00000");
    Config->MessagePerHour_Move = 360;
    Config->MessagePerHour_Idle = 10;   
    Config->ServerMessagePerHour = 60;
    strcpy(Config->HTTPServerAddr, "115.84.179.74");
    strcpy(Config->HTTPServerPort, "7979");
    strcpy(Config->HTTPServerAddr2, "115.84.179.74");
    strcpy(Config->HTTPServerPort2, "7878");
    Config->PulseOnKm = 2540;
    Config->ActiveOnHigh_AC = 0;
    Config->ActiveOnHigh_Door = 0;
    Config->ActiveOnHigh_Engine = 0;  
    Config->OfflineMode = 0; // Dong: for test
    Config->WarningVelocity = 80;
    strcpy(Config->FirmwareDir, "fw_ufw");
    strcpy(Config->FirmwarePrefix, "bufw");
    strcpy(Config->DriverName, "LAI XE A");
    strcpy(Config->VIN, "0123456789ABCDEFG");
    Config->HTTP_ProtocolEnable = 1;
}

char _line[512];

extern void SPANSION_Band0_Select(void);
extern void SPANSION_Band0_Deselect(void);
extern void SPANSION_Band1_Select(void);
extern void SPANSION_Band1_Deselect(void);

extern void SD_Select(void);
extern void SD_Deselect(void);

void vbb_STORAGE_Init(void)
{    
    STORAGE_DefaultConfig(&(storage.config));                   
    
    /*
    storage.flash.numOfPages = flashMem.flash.numOfPages;
    storage.flash.pageSize = flashMem.flash.pageSize;
    
    if (vbb_DeviceModel() == CNS03)
        vbb_PIN_Init(&(storage.flash.select_pin), GPIOE, 13, PIN_MODE_GENERAL_OUTPUT_PUSH_PULL);
    else if (vbb_DeviceModel() == CNS01)
        vbb_PIN_Init(&(storage.flash.select_pin), GPIOB, 1, PIN_MODE_GENERAL_OUTPUT_PUSH_PULL);
    else if (vbb_DeviceModel() == BA01)
        vbb_PIN_Init(&(storage.flash.select_pin), GPIOB, 1, PIN_MODE_GENERAL_OUTPUT_PUSH_PULL);

    storage.flash.spi.pin_clk = flashMem.flash.spi.pin_clk;    
    storage.flash.spi.pin_miso = flashMem.flash.spi.pin_miso;
    storage.flash.spi.pin_mosi = flashMem.flash.spi.pin_mosi;
    storage.flash.spi.SPIx = flashMem.flash.spi.SPIx;    
    */
    
    if (vbb_DeviceModel() == CNS03)
        vbb_Flash_Init(&(storage.flash), 256, 65536, SPI3, GPIOE, 12);
    else if (vbb_DeviceModel() == CNS01 || vbb_DeviceModel() == BA01)
        vbb_Flash_Init(&(storage.flash), 256, 65536, SPI3, GPIOB, 0);
    
    /*
    vbb_OUTPUT_Print("INFO: SPANSION band 1 information: ");
    vbb_OUTPUT_PrintNumberUnSigned(vbb_Flash_ReadId(&(storage.flash)));
    vbb_OUTPUT_Print(" ");
    vbb_OUTPUT_PrintNumberUnSigned(vbb_Flash_ReadElectronicSignature(&(storage.flash)));
    vbb_OUTPUT_Print("\r\n");
    */
    
    /*vbb_CONSOLE_Printf("INFO: SPANSION die 1 information: %2xh %2xh.\r\n", vbb_Flash_ReadId(&(storage.flash)), vbb_Flash_ReadElectronicSignature(&(storage.flash)));*/
    
    /*vbb_Flash_UnlockFlash(&(storage.flash));*/
    
    vbb_STORAGE_ReadConfig();  
}

char _tmpStr[128];

void STORAGE_GetString(const char * Line, char * Str)
{
    char * tmp = Str;
    while ((Line[0] >= 'a' && Line[0] <= 'z') || (Line[0] >= 'A' && Line[0] <= 'Z') || (Line[0] >= '0' && Line[0] <= '9') || (Line[0] == '-') || (Line[0] == '.'))
    {
        tmp[0] = Line[0];
        tmp++;
        Line++;
    }
    tmp[0] = 0;
}

#ifdef CONFIG_STM32G_MAINTAIN
void STORAGE_GetTotalString(const char * Line, char * Str)
{
    memcpy(Str, Line, vbb_GetLen(Line));
}
void vbb_STORAGE_SaveConfig(void)
{
    unsigned int base_flash_addr = STORAGE_ADDR_CONFIG;
    unsigned int write_addr = base_flash_addr;    

    vbb_CONSOLE_Printf("(erase sector 0x%x)", write_addr);
    vbb_Flash_EraseSector(&(storage.flash), write_addr);

    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_OWNERID * STORAGE_PAGE_SIZE;
    sprintf(storage.flash.tmpPage, "%s%s", OWNERID_STR, storage.config.OwnerId);
    vbb_Flash_PageProgram(&(storage.flash), write_addr);

    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_VEHICLEID* STORAGE_PAGE_SIZE; 
    sprintf(storage.flash.tmpPage, "%s%s", VEHICLEID_STR, storage.config.VehicleId);
    vbb_Flash_PageProgram(&(storage.flash), write_addr);

    
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_PLATE* STORAGE_PAGE_SIZE; 
    sprintf(storage.flash.tmpPage, "%s%s", PLATE_STR, storage.config.PlateNumber);    
    vbb_Flash_PageProgram(&(storage.flash), write_addr);    
    
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_MSGPERHOUR_MOVE* STORAGE_PAGE_SIZE;
    sprintf(storage.flash.tmpPage, "%s%d", MSGPERHOUR_MOVE_STR, storage.config.MessagePerHour_Move);
    vbb_Flash_PageProgram(&(storage.flash), write_addr);
    
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_MSGPERHOUR_IDLE* STORAGE_PAGE_SIZE;
    sprintf(storage.flash.tmpPage, "%s%d", MSGPERHOUR_IDLE_STR, storage.config.MessagePerHour_Idle);
    vbb_Flash_PageProgram(&(storage.flash), write_addr);
        
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_HTTP* STORAGE_PAGE_SIZE;
    sprintf(storage.flash.tmpPage, "%s%s,%s", HTTP_STR, storage.config.HTTPServerAddr,storage.config.HTTPServerPort);
    vbb_Flash_PageProgram(&(storage.flash), write_addr);
        
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_HTTP2* STORAGE_PAGE_SIZE; 
    sprintf(storage.flash.tmpPage, "%s%s,%s", HTTP2_STR, storage.config.HTTPServerAddr2,storage.config.HTTPServerPort2);   
    vbb_Flash_PageProgram(&(storage.flash), write_addr);
        
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_PULSEONKM* STORAGE_PAGE_SIZE;
    sprintf(storage.flash.tmpPage, "%s%d", PULSEKM_STR, storage.config.PulseOnKm);
    vbb_Flash_PageProgram(&(storage.flash), write_addr);
    
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_WARNINGVEL* STORAGE_PAGE_SIZE; 
    sprintf(storage.flash.tmpPage, "%s%d", WARNING_SPEED_STR, storage.config.WarningVelocity);    
    vbb_Flash_PageProgram(&(storage.flash), write_addr);
    
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_VIN* STORAGE_PAGE_SIZE;
    sprintf(storage.flash.tmpPage, "%s%s", VIN_STR, storage.config.VIN);    
    vbb_Flash_PageProgram(&(storage.flash), write_addr);
       
    memset(storage.flash.tmpPage, 0x00, FLASH_PAGE_BUF_LEN);
    write_addr = base_flash_addr + FLASH_OFFSET_DRIVER* STORAGE_PAGE_SIZE;
    sprintf(storage.flash.tmpPage, "%s%s", DRIVER_STR, storage.config.DriverName);    
    vbb_Flash_PageProgram(&(storage.flash), write_addr);    
}
#endif

bool vbb_STORAGE_CheckConfig(const char * ConfigLine)
{
    return strstr(ConfigLine, "CK+CONFIG,") != NULL;
}

int vbb_CommandAnalysis(const char *ConfigLine)
{       
      char * str_position = NULL;
      char tmpstr[128];

      memset(tmpstr, 0x0, sizeof(tmpstr));
      str_position = vbb_FindStr(ConfigLine, OWNERID_STR);
      if(NULL != str_position)
      {        
          str_position += vbb_GetLen(OWNERID_STR);
          if(OWNERID_LEN < vbb_GetLen(str_position))
          {
              vbb_CONSOLE_Printf("OwnerID length should be less than %d charaters\n", OWNERID_LEN);   
              return -1;      
          }     
          memset(storage.config.OwnerId, 0x00, OWNERID_LEN);
          STORAGE_GetTotalString(str_position, storage.config.OwnerId);
          return 0;
      } 
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, VEHICLEID_STR)))
      {
          str_position += vbb_GetLen(VEHICLEID_STR);
          if(VEHICLEID_LEN < vbb_GetLen(str_position))
          {
              vbb_CONSOLE_Printf("VehicleID length should be less than %d characters\n", VEHICLEID_LEN);
              return -1;
          }

          memset(storage.config.VehicleId, 0x00, VEHICLEID_LEN);
          STORAGE_GetTotalString(str_position, storage.config.VehicleId);
          return 0;
      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, PLATE_STR)))
      { 
          str_position += vbb_GetLen(PLATE_STR);
          if(PLATENUMBER_LEN < vbb_GetLen(str_position))
          {
              vbb_CONSOLE_Printf("Plate number length should be less than %d characters\n", PLATENUMBER_LEN);
              return -1;
          }
          memset(storage.config.PlateNumber, 0x00, PLATENUMBER_LEN);
          STORAGE_GetTotalString(str_position, storage.config.PlateNumber);          
          return 0;
      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, MSGPERHOUR_MOVE_STR)))
      { 
          str_position += vbb_GetLen(MSGPERHOUR_MOVE_STR);
          STORAGE_GetString(str_position, tmpstr);
          storage.config.MessagePerHour_Move = atoi(tmpstr);
          return 0;

      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, MSGPERHOUR_IDLE_STR)))
      { 
          str_position += vbb_GetLen(MSGPERHOUR_IDLE_STR);
          STORAGE_GetString(str_position, tmpstr);
          storage.config.MessagePerHour_Idle = atoi(tmpstr);
          return 0;

      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, HTTP_STR)))
      { 
          str_position += vbb_GetLen(HTTP_STR);
          if(HTTP_ADDR_LEN < vbb_GetLen(str_position))
          {
              vbb_CONSOLE_Printf("HTTP address length should be less than %d characters\n", HTTP_ADDR_LEN);
              return -1;           
          }

          memset(storage.config.HTTPServerAddr, 0x00, HTTP_ADDR_LEN);
          STORAGE_GetString(str_position, storage.config.HTTPServerAddr);
          str_position += vbb_GetLen(storage.config.HTTPServerAddr);
          if(str_position[0] == ',')
          {
               memset(storage.config.HTTPServerPort, 0x00, HTTP2_ADDR_PORT_LEN); 
               STORAGE_GetString(str_position + 1, storage.config.HTTPServerPort); 
          }
          return 0;

      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, HTTP2_STR)))
      { 
          str_position += vbb_GetLen(HTTP2_STR);
          if(HTTP2_ADDR_LEN < vbb_GetLen(str_position))
          {
              vbb_CONSOLE_Printf("HTTP2 address length should be less than %d characters\n", HTTP2_ADDR_LEN);
              return -1;           
          }           
          memset(storage.config.HTTPServerAddr2, 0x00, HTTP2_ADDR_LEN);
          STORAGE_GetString(str_position, storage.config.HTTPServerAddr2);
          str_position += vbb_GetLen(storage.config.HTTPServerAddr2);
          if(str_position[0] == ',')
          {
               memset(storage.config.HTTPServerPort2, 0x00, HTTP2_ADDR_PORT_LEN); 
               STORAGE_GetString(str_position + 1, storage.config.HTTPServerPort2); 
          }              
          return 0;
      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, PULSEKM_STR)))  
      {
          str_position += vbb_GetLen(PULSEKM_STR);
          STORAGE_GetString(str_position, tmpstr);
          storage.config.PulseOnKm = atoi(tmpstr);
          return 0;

      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, WARNING_SPEED_STR)))
      {
          str_position += vbb_GetLen(WARNING_SPEED_STR);
          STORAGE_GetString(str_position, tmpstr);
          storage.config.WarningVelocity = atoi(tmpstr);
          return 0;

      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, VIN_STR)))
      {
          str_position += vbb_GetLen(VIN_STR);
          if(VIN_LEN< vbb_GetLen(str_position))
          {
              vbb_CONSOLE_Printf("VIN length should be less than %d characters\n", VIN_LEN);
              return -1;           
          }                   
          memset(storage.config.VIN, 0x00, VIN_LEN);
          STORAGE_GetTotalString(str_position, storage.config.VIN);
          return 0;       
      }
      else if (NULL != (str_position = vbb_FindStr(ConfigLine, DRIVER_STR)))
      {          
          str_position += vbb_GetLen(DRIVER_STR);
          if(DRIVERNAME_LEN < vbb_GetLen(str_position))
          {
              vbb_CONSOLE_Printf("Driver name length should be less than %d characters\n", DRIVERNAME_LEN);
              return -1;           
          }                
          memset(storage.config.DriverName, 0x00, DRIVERNAME_LEN);
          STORAGE_GetTotalString(str_position, storage.config.DriverName);
          return 0;       
      }
      return -1;        
}

void vbb_STORAGE_Dump(void)
{
        vbb_CONSOLE_Printf("CONFIG: ownerid,%s\r\n", storage.config.OwnerId);
        vbb_CONSOLE_Printf("CONFIG: vehicleid,%s\r\n", storage.config.VehicleId);
        vbb_CONSOLE_Printf("CONFIG: plate,%s\r\n", storage.config.PlateNumber);
        vbb_CONSOLE_Printf("CONFIG: msgperhour_move,%d\r\n", storage.config.MessagePerHour_Move);
        vbb_CONSOLE_Printf("CONFIG: msgperhour_idle,%d\r\n", storage.config.MessagePerHour_Idle);
        vbb_CONSOLE_Printf("CONFIG: http,%s:%s\r\n", storage.config.HTTPServerAddr, storage.config.HTTPServerPort);
        vbb_CONSOLE_Printf("CONFIG: http2,%s:%s\r\n", storage.config.HTTPServerAddr2, storage.config.HTTPServerPort2);
        vbb_CONSOLE_Printf("CONFIG: pulseonkm,%d\r\n", storage.config.PulseOnKm);
        vbb_CONSOLE_Printf("CONFIG: active_door,%d\r\n", storage.config.ActiveOnHigh_Door);
        vbb_CONSOLE_Printf("CONFIG: active_engine,%d\r\n", storage.config.ActiveOnHigh_Engine);
        vbb_CONSOLE_Printf("CONFIG: active_ac,%d\r\n", storage.config.ActiveOnHigh_AC);    
        vbb_CONSOLE_Printf("CONFIG: offline,%d\r\n", storage.config.OfflineMode);
        vbb_CONSOLE_Printf("CONFIG: fwdir,%s\r\n", storage.config.FirmwareDir);
        vbb_CONSOLE_Printf("CONFIG: fwprefix,%s\r\n", storage.config.FirmwarePrefix);
        vbb_CONSOLE_Printf("CONFIG: driver,%s\r\n", storage.config.DriverName);
        vbb_CONSOLE_Printf("CONFIG: vin,%s\r\n", storage.config.VIN);
        vbb_CONSOLE_Printf("CONFIG: warningvel,%d\r\n", storage.config.WarningVelocity);
        vbb_CONSOLE_Printf("CONFIG: push,%d\r\n", storage.config.ServerMessagePerHour);
        vbb_CONSOLE_Printf("CONFIG: http_protocol,%d\r\n", storage.config.HTTP_ProtocolEnable);
}


void vbb_STORAGE_ReadConfig(void)
{
#ifndef CONFIG_STM32G_MAINTAIN        
    unsigned int Addr = STORAGE_ADDR_CONFIG;
    char * ln;
    int count = 0;
    
    vbb_OUTPUT_Print("INFO: Read configuration.\r\n");
    
    vbb_Flash_PageRead(&(storage.flash), Addr);
    vbb_StrCpy(_line, storage.flash.tmpPage, 256);
    
    if (_line[0] != (char)0xFF && _line[0] != 'C')
    {
        vbb_OUTPUT_Print("INFO: Format configuration storage ");
        vbb_STORAGE_Clear();
        vbb_OUTPUT_Print("[DONE]\r\n");
    }
    
    while (_line[0] == 'C' && _line[1] == 'K' && count < STORAGE_MAX_CONFIG)
    {
        ln = vbb_FindStr(_line, "CK+CONFIG,");
        if (ln)
        {
            if ((ln = vbb_FindStr(_line, "ownerid,")) != 0)
            {                
                ln += vbb_GetLen("ownerid,");                                
                STORAGE_GetString(ln, storage.config.OwnerId);
            }             
            else if ((ln = vbb_FindStr(_line, "vehicleid,")) != 0)
            {
                ln += vbb_GetLen("vehicleid,");
                STORAGE_GetString(ln, storage.config.VehicleId);
            }
            else if ((ln = vbb_FindStr(_line, "plate,")) != 0)
            {
                ln += vbb_GetLen("plate,");
                STORAGE_GetString(ln, storage.config.PlateNumber);
                
                vbb_CONSOLE_Printf("INFO: Config plate %s.\r\n", storage.config.PlateNumber);
            }
            else if ((ln = vbb_FindStr(_line, "fwdir,")) != 0)
            {
                ln += vbb_GetLen("fwdir,");
                STORAGE_GetString(ln, storage.config.FirmwareDir);
            }
            else if ((ln = vbb_FindStr(_line, "fwprefix,")) != 0)
            {
                ln += vbb_GetLen("fwprefix,");
                STORAGE_GetString(ln, storage.config.FirmwarePrefix);
            }            
            else if ((ln = vbb_FindStr(_line, "vin,")) != 0)
            {
                ln += vbb_GetLen("vin,");
                STORAGE_GetString(ln, storage.config.VIN);
            }
            else if ((ln = vbb_FindStr(_line, "driver,")) != 0)
            {
                ln += vbb_GetLen("driver,");
                STORAGE_GetString(ln, storage.config.DriverName);
            }
            else if ((ln = vbb_FindStr(_line, "http,")) != 0)
            {
                ln += vbb_GetLen("http,");
                STORAGE_GetString(ln, storage.config.HTTPServerAddr);
                ln += vbb_GetLen(storage.config.HTTPServerAddr);
                if (ln[0] == ',')
                    STORAGE_GetString(ln + 1, storage.config.HTTPServerPort);
            }
            else if ((ln = vbb_FindStr(_line, "http2,")) != 0)
            {
                ln += vbb_GetLen("http2,");
                STORAGE_GetString(ln, storage.config.HTTPServerAddr2);
                ln += vbb_GetLen(storage.config.HTTPServerAddr2);
                if (ln[0] == ',')
                    STORAGE_GetString(ln + 1, storage.config.HTTPServerPort2);
            }
            else if ((ln = vbb_FindStr(_line, "msgperhour_move,")) != 0)
            {
                ln += vbb_GetLen("msgperhour_move,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.MessagePerHour_Move = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "msgperhour_idle,")) != 0)
            {
                ln += vbb_GetLen("msgperhour_idle,");                
                STORAGE_GetString(ln, _tmpStr);
                storage.config.MessagePerHour_Idle = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "pulseonkm,")) != 0)
            {
                ln += vbb_GetLen("pulseonkm,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.PulseOnKm = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "warningvel,")) != 0)
            {
                ln += vbb_GetLen("warningvel,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.WarningVelocity = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "active_door,")) != 0)
            {
                ln += vbb_GetLen("active_door,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.ActiveOnHigh_Door = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "active_engine,")) != 0)
            {
                ln += vbb_GetLen("active_engine,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.ActiveOnHigh_Engine = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "active_ac,")) != 0)
            {
                ln += vbb_GetLen("active_ac,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.ActiveOnHigh_AC = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "offline,")) != 0)
            {
                ln += vbb_GetLen("offline,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.OfflineMode = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "push,")) != 0)
            {
                ln += vbb_GetLen("push,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.ServerMessagePerHour = atoi(_tmpStr);
            }
            else if ((ln = vbb_FindStr(_line, "http_protocol,")) != 0)
            {
                ln += vbb_GetLen("http_protocol,");
                STORAGE_GetString(ln, _tmpStr);
                storage.config.HTTP_ProtocolEnable = atoi(_tmpStr);
            }
            
            Addr += STORAGE_PAGE_SIZE;
            vbb_Flash_PageRead(&(storage.flash), Addr);
            vbb_StrCpy(_line, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
            
            count++;
        }
        else
            break;
    }        
#else    
    unsigned int base_flash_addr = STORAGE_ADDR_CONFIG;
    unsigned int read_addr;        
    char * str_position = NULL;
#define TMPSTR_LEN 128   
    char tmpstr[TMPSTR_LEN];
    char config_mess[STORAGE_PAGE_SIZE];
//    int msgperhour_move=0;
//    int msgperhour_idle=0;
    
    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);
    memset(tmpstr, 0x00, TMPSTR_LEN);
    read_addr = base_flash_addr + FLASH_OFFSET_OWNERID * STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, OWNERID_STR);
    if(NULL != str_position)
    {
         str_position += vbb_GetLen(OWNERID_STR);
         STORAGE_GetString(str_position, storage.config.OwnerId);
    }

    memset(config_mess, 0x00, STORAGE_PAGE_SIZE); 
    read_addr = base_flash_addr + FLASH_OFFSET_VEHICLEID* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
//    vbb_CONSOLE_Printf("VehicleID message : %s\n", config_mess);
    str_position = vbb_FindStr(config_mess, VEHICLEID_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(VEHICLEID_STR);        
        STORAGE_GetString(str_position, storage.config.VehicleId);
    }

    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);    
    read_addr = base_flash_addr + FLASH_OFFSET_PLATE* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, PLATE_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(PLATE_STR);      
        STORAGE_GetString(str_position, storage.config.PlateNumber);
    }    

    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);
    memset(tmpstr, 0x00, TMPSTR_LEN);
    read_addr = base_flash_addr + FLASH_OFFSET_MSGPERHOUR_MOVE* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, MSGPERHOUR_MOVE_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(MSGPERHOUR_MOVE_STR);
        STORAGE_GetString(str_position, tmpstr);
        storage.config.MessagePerHour_Move= atoi(tmpstr);
    }    
    

    memset(tmpstr, 0x00, TMPSTR_LEN);
    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);
    read_addr = base_flash_addr + FLASH_OFFSET_MSGPERHOUR_IDLE* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, MSGPERHOUR_IDLE_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(MSGPERHOUR_IDLE_STR);
        STORAGE_GetString(str_position, tmpstr);
        storage.config.MessagePerHour_Idle= atoi(tmpstr);
        vbb_CONSOLE_Printf("MsgPerHour_Idle : %d\n", storage.config.MessagePerHour_Idle);
    }    

    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);
    read_addr = base_flash_addr + FLASH_OFFSET_HTTP* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, HTTP_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(HTTP_STR);
        STORAGE_GetString(str_position, storage.config.HTTPServerAddr);
        str_position += vbb_GetLen(storage.config.HTTPServerAddr);
        if(str_position[0] == ',')
          {
               STORAGE_GetString(str_position + 1, storage.config.HTTPServerPort); 
          }
    }

    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);
    read_addr = base_flash_addr + FLASH_OFFSET_HTTP2* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, HTTP2_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(HTTP2_STR);
        STORAGE_GetString(str_position, storage.config.HTTPServerAddr2);
        str_position += vbb_GetLen(storage.config.HTTPServerAddr2);
        if(str_position[0] == ',')
          {
               STORAGE_GetString(str_position + 1, storage.config.HTTPServerPort2); 
          }
    } 
    
    memset(tmpstr, 0x00, TMPSTR_LEN);
    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);    
    read_addr = base_flash_addr + FLASH_OFFSET_PULSEONKM* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, PULSEKM_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(PULSEKM_STR);
        STORAGE_GetString(str_position, tmpstr);
        storage.config.PulseOnKm= atoi(tmpstr);

    } 
    
    memset(tmpstr, 0x00, TMPSTR_LEN);
    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);   
    read_addr = base_flash_addr + FLASH_OFFSET_WARNINGVEL* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, WARNING_SPEED_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(WARNING_SPEED_STR);
        STORAGE_GetString(str_position, tmpstr);
        storage.config.WarningVelocity= atoi(tmpstr);
    }    

    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);
    read_addr = base_flash_addr + FLASH_OFFSET_VIN* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, VIN_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(VIN_STR);        
        STORAGE_GetString(str_position, storage.config.VIN);        
    }    

    memset(config_mess, 0x00, STORAGE_PAGE_SIZE);
    read_addr = base_flash_addr + FLASH_OFFSET_DRIVER* STORAGE_PAGE_SIZE;
    vbb_Flash_PageRead(&(storage.flash), read_addr);
    vbb_StrCpy(config_mess, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    str_position = vbb_FindStr(config_mess, DRIVER_STR);    
    if(NULL != str_position)
    {
        str_position += vbb_GetLen(DRIVER_STR);         
        STORAGE_GetString(str_position, storage.config.DriverName);        
    }    

#endif

#ifdef CONFIG_STM32G_MAINTAIN    
    vbb_CONSOLE_Printf("CONFIG: ownerid,%s\r\n", storage.config.OwnerId);
    vbb_CONSOLE_Printf("CONFIG: vehicleid,%s\r\n", storage.config.VehicleId);
    vbb_CONSOLE_Printf("CONFIG: plate,%s\r\n", storage.config.PlateNumber);
    vbb_CONSOLE_Printf("CONFIG: msgperhour_move,%d\r\n", storage.config.MessagePerHour_Move);
    vbb_CONSOLE_Printf("CONFIG: msgperhour_idle,%d\r\n", storage.config.MessagePerHour_Idle);
    vbb_CONSOLE_Printf("CONFIG: http,%s:%s\r\n", storage.config.HTTPServerAddr, storage.config.HTTPServerPort);
    vbb_CONSOLE_Printf("CONFIG: http2,%s:%s\r\n", storage.config.HTTPServerAddr2, storage.config.HTTPServerPort2);
    vbb_CONSOLE_Printf("CONFIG: pulseonkm,%d\r\n", storage.config.PulseOnKm);
    vbb_CONSOLE_Printf("CONFIG: active_door,%d\r\n", storage.config.ActiveOnHigh_Door);
    vbb_CONSOLE_Printf("CONFIG: active_engine,%d\r\n", storage.config.ActiveOnHigh_Engine);
    vbb_CONSOLE_Printf("CONFIG: active_ac,%d\r\n", storage.config.ActiveOnHigh_AC);    
    vbb_CONSOLE_Printf("CONFIG: offline,%d\r\n", storage.config.OfflineMode);
    vbb_CONSOLE_Printf("CONFIG: fwdir,%s\r\n", storage.config.FirmwareDir);
    vbb_CONSOLE_Printf("CONFIG: fwprefix,%s\r\n", storage.config.FirmwarePrefix);
    vbb_CONSOLE_Printf("CONFIG: driver,%s\r\n", storage.config.DriverName);
    vbb_CONSOLE_Printf("CONFIG: vin,%s\r\n", storage.config.VIN);
    vbb_CONSOLE_Printf("CONFIG: warningvel,%d\r\n", storage.config.WarningVelocity);
    vbb_CONSOLE_Printf("CONFIG: push,%d\r\n", storage.config.ServerMessagePerHour);
    vbb_CONSOLE_Printf("CONFIG: http_protocol,%d\r\n", storage.config.HTTP_ProtocolEnable);
#endif    
}

extern unsigned int FLASHMEM_GetSectorSize(unsigned int Address);

void vbb_STORAGE_AddConfig(const char * ConfigLine)
{
#ifndef CONFIG_STM32G_MAINTAIN
    unsigned int Addr = STORAGE_ADDR_CONFIG;    
    int count = 0;
    
    vbb_OUTPUT_Print("INFO: Add config \"");
    vbb_OUTPUT_PrintDebug(ConfigLine);
    vbb_OUTPUT_Print("\"");
    
    vbb_Flash_PageRead(&(storage.flash), Addr);
    vbb_StrCpy(_line, storage.flash.tmpPage, STORAGE_PAGE_SIZE);
    
    while (_line[0] == 'C' && _line[1] == 'K' && count < STORAGE_MAX_CONFIG)
    {                     
        vbb_OUTPUT_PrintDebug(_line);
        vbb_OUTPUT_Print("\r\n");        
        Addr += STORAGE_PAGE_SIZE;
        vbb_Flash_PageRead(&(storage.flash), Addr);
        vbb_StrCpy(_line, storage.flash.tmpPage, STORAGE_PAGE_SIZE);  
        count++;
    }
    
    if (count < 256)
    {
        if (Addr % FLASHMEM_GetSectorSize(Addr) == 0)    
        {
            vbb_CONSOLE_Printf("(erase sector 0x%x)", Addr);
            vbb_Flash_EraseSector(&(storage.flash), Addr);
        }
        
        vbb_StrCpy(storage.flash.tmpPage, ConfigLine, STORAGE_PAGE_SIZE);
        vbb_Flash_PageProgram(&(storage.flash), Addr);
        
        vbb_OUTPUT_Print("[DONE]\r\n");
    }
    else
    {
        vbb_OUTPUT_Print("[FAIL]\r\n");
    }
#else
    int ret;
    char * str_position = NULL;
    unsigned int mess_len; 
    
    mess_len = vbb_GetLen(ConfigLine);
    if(STORAGE_PAGE_SIZE < mess_len)
    {
        vbb_CONSOLE_Printf("Configuration message length should less than 256 bytes\n");
        return;
    }
    str_position = vbb_FindStr(ConfigLine, CONFIG_STR);
    if(NULL == str_position)
    {
         vbb_CONSOLE_Printf("Config command should be CK+CONFIG,Item,Item\n");     
         return;
    }
    ret = vbb_CommandAnalysis(ConfigLine);
    if(0 > ret)
    {
        vbb_CONSOLE_Printf("Unknown Command 2\n");     
        return;
    }

#endif
}

void vbb_STORAGE_Clear(void)
{
    vbb_Flash_EraseSector(&(storage.flash), STORAGE_ADDR_CONFIG);    
}

#endif
